// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//
#include <memory>
#include <vector>

#include <pollux/expression/expr.h>
#include <pollux/vector/base_vector.h>

namespace kumo::pollux::functions::sparksql {
    // These functions delegate to the RE2-based implementations in
    // lib/Re2Functions.h, but check to ensure that syntax that has different
    // semantics between Spark (which uses java.util.regex) and RE2 throws an
    // error.
    //
    // Some incompatibilities:
    // - \h, \H, \v, \V - horizontal and vertical whitespace classes
    // - \s - in RE2, does not include \x0B (vertical tab) unlike java.util.
    // - character class union, intersection and difference ([a[b]], [a&&[b]] and
    //   [a&&[^b]])
    // - \uHHHH for four-digit hex code HHHH
    // - \e for escape (\033)
    // - \cK for control character K
    // - \p{X} - supported Unicode character class names differ
    // - \G - end of previous match
    // - \Z - end of the input except the final terminator(?)
    // - \R - any linebreak
    // - Features related to backtracking (which RE2 explicitly does not support):
    //   - Backreferences
    //   - Possessive quantifiers (these disable backtracking)
    //   - Lookahead (?=...), (?!...), (?<=...), (?<!...)
    //   - (?>...) as an independent non-capturing group (i.e. backtracking
    //     disabled)
    //
    // Character class set operations are the only case where re2 would interpret
    // the regex differently than Spark expects, so we throw an error on these
    // patterns. At the moment this is implemented in a way that requires the
    // pattern is a constant.

    std::shared_ptr<exec::VectorFunction> makeRLike(
        const std::string &name,
        const std::vector<exec::VectorFunctionArg> &inputArgs,
        const core::QueryConfig &config);

    std::shared_ptr<exec::VectorFunction> makeRegexExtract(
        const std::string &name,
        const std::vector<exec::VectorFunctionArg> &inputArgs,
        const core::QueryConfig &config);

    /// Full implementation of RegexReplace found in SparkSQL only,
    /// due to semantic mismatches betweeen Spark and Presto
    /// regexp_replace(string, pattern, overwrite) → string
    /// regexp_replace(string, pattern, overwrite, position) → string
    ///
    /// If a string has a substring that matches the given pattern, replace
    /// the match in the string with overwrite and return the string. If
    /// optional parameter position is provided, only make replacements
    /// after that positon in the string (1 indexed).
    ///
    /// If position <= 0, throw error.
    /// If position > length string, return string.
    void registerRegexpReplace(const std::string &prefix);
} // namespace kumo::pollux::functions::sparksql
